// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2007
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class TaskPreprocessDriveImage
    {
        #region Fields
        // input
        private Bitmap _DRIVEImage;
        private Bitmap _maskImage;        
        private Bitmap _manualImage;
        // output
        private Bitmap _DSAImage;
        private Bitmap _manualCentreLineImage;
        #endregion

        #region Properties
        public Bitmap DSAImage { get { return _DSAImage; } }
        public Bitmap ManualCentreLineImage { get { return _manualCentreLineImage; } }
        #endregion

        #region Constructor
        public TaskPreprocessDriveImage(Bitmap DRIVEImage, Bitmap maskImage, Bitmap manualImage)
        {
            _DRIVEImage = DRIVEImage;
            _maskImage = maskImage;
            _manualImage = manualImage;
        }     
        #endregion    

        public void Preprocess()
        {
             _DSAImage = PreprocessDRIVEImage(_DRIVEImage, _maskImage);
             _manualCentreLineImage = PreprocessManualImage(_manualImage);
        } // Preprocess()

        private Bitmap PreprocessDRIVEImage(Bitmap DRIVEImage, Bitmap maskImage)
        {
            // gree channel
            ColourChannel channelFilter = new ColourChannel(ColourChannelEnum.G);
            Bitmap greenChannelImage = channelFilter.ApplyColourImageFilter(DRIVEImage);
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref greenChannelImage);

            PZMath_matrix ROIMatrix = GetROIMatrix(maskImage);
            
            // median filter
            int kernelSize = 21;
            int percentile = 40;
            Median medianFilter = new Median(kernelSize, percentile, ROIMatrix);
            Bitmap backgroundImage = medianFilter.ApplyGraylevelImageFilter(greenChannelImage);            
           
            // substraction
            TwoImageMinus twoImageMinusFilter = new TwoImageMinus(backgroundImage);
            Bitmap dstImage = twoImageMinusFilter.ApplyGraylevelImageFilter(greenChannelImage);
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref dstImage);

            return dstImage;
        } // Preprocess()

        private PZMath_matrix GetROIMatrix(Bitmap maskImage)
        {
            Bitmap srcImage = (Bitmap)maskImage.Clone();
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref srcImage);
            ConvertBitmapMatrix converter = new ConvertBitmapMatrix();
            PZMath_matrix ROIMatrix = converter.GetROIMatrix(srcImage);
            return ROIMatrix;
        } // GetROIMatrix()

        private Bitmap PreprocessManualImage(Bitmap manualImage)
        {
            Negative negativeFilter = new Negative();
            Bitmap negativeManualImage = negativeFilter.ApplyGraylevelImageFilter(manualImage);
            RockettThinning thinningFilter = new RockettThinning();
            Bitmap manualCenterLineImage = thinningFilter.ApplyGraylevelImageFilter(negativeManualImage);
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref manualCenterLineImage);
            
            return manualCenterLineImage;
        } // PreprocessManualImage()

        public void WriteDSAImage(string fileName)
        {
            _DSAImage.Save(fileName);
        } // WriteDSAImage()

        public void WriteManualCentreLineImage(string fileName)
        {
            _manualCentreLineImage.Save(fileName);
        } // WriteManualCentreLineImage()
    }
}
